import { Controller, Param, Body, Get, Post, Put, QueryParams, Req, Res } from 'routing-controllers';
import { Container } from 'typedi';
import { UserService } from '@services/users.service';
import { CreateUserDto, ResetPasswordDto, UpdateMyselfDto, UpdateUserDto, UserPageDto } from '@/dtos';
import { Request, Response } from 'express';
import { ApiResponseBuilder } from '@utils/api-response-builder';
import { OpenAPI } from 'routing-controllers-openapi';
import { Log, LogOperation } from '@decorators/logs.decorators';
import { RequestWithUser } from '@/interfaces';
import { RequiredPerm } from '@decorators/perm.decorator';

@Controller('/user')
export class UserController {
  public user = Container.get(UserService);

  @Get('/page')
  @RequiredPerm('user:page')
  @OpenAPI({ summary: '用户分页查询' })
  async findAll(@QueryParams() pageDto: UserPageDto, @Req() req: Request, @Res() res: Response) {
    const { list = [], total } = await this.user.findAll(pageDto);
    return new ApiResponseBuilder(req, res).paginate(list, total, pageDto.pageNum || 1, pageDto.pageSize || 20);
  }

  @Get('/detail')
  @OpenAPI({ summary: '获取用户详情' })
  async getMyselfDetail(@Req() req: RequestWithUser, @Res() res: Response) {
    const { id } = req.user;
    const user = await this.user.findOne(id);
    return new ApiResponseBuilder(req, res).success(user, undefined);
  }

  @Get('/detail/:id')
  @RequiredPerm('user:detail')
  @OpenAPI({ summary: '管理员获取用户详情' })
  async findOne(@Param('id') id: string, @Req() req: Request, @Res() res: Response) {
    const user = await this.user.findOne(id);
    return new ApiResponseBuilder(req, res).success(user, undefined);
  }

  @Post('/create')
  @RequiredPerm('user:create')
  @OpenAPI({ summary: '创建用户' })
  @Log({
    bizType: 'users',
    operation: LogOperation.CREATE,
    bizId: (req: { user: { id: string } }) => 'user_create_' + (req?.user?.id ?? ''),
  })
  async create(@Req() req: Request, @Res() res: Response, @Body() dto: CreateUserDto) {
    await this.user.create(dto);
    return new ApiResponseBuilder(req, res).success();
  }

  @Put('/update')
  @OpenAPI({ summary: '修改用户自身信息' })
  @Log({
    bizType: 'users',
    operation: LogOperation.UPDATE,
    bizId: (req: { user: { id: string } }) => 'user_update_' + (req?.user?.id ?? ''),
  })
  async updateMyself(@Req() req: RequestWithUser, @Res() res: Response, @Body() dto: UpdateMyselfDto) {
    const { id } = req.user;
    await this.user.update(id, dto);
    return new ApiResponseBuilder(req, res).success();
  }

  @Put('/update/:id')
  @RequiredPerm('user:update')
  @OpenAPI({ summary: '更新用户' })
  @Log({
    bizType: 'users',
    operation: LogOperation.UPDATE,
    bizId: (req: { user: { id: string } }) => 'user_update_' + (req?.user?.id ?? ''),
  })
  async update(@Req() req: Request, @Res() res: Response, @Param('id') id: string, @Body() dto: UpdateUserDto) {
    await this.user.update(id, dto);
    return new ApiResponseBuilder(req, res).success();
  }

  @Post('/reset-password')
  @OpenAPI({ summary: '修改密码' })
  @Log({
    bizType: 'users',
    operation: LogOperation.UPDATE,
    bizId: (req: { user: { id: string } }) => 'user_reset_password_' + (req?.user?.id ?? ''),
  })
  async resetPassword(@Req() req: RequestWithUser, @Res() res: Response, @Body() dto: ResetPasswordDto) {
    await this.user.changePassword(req, dto);
    return new ApiResponseBuilder(req, res).success();
  }

  @Put('/update/status/:id')
  @RequiredPerm('user:update:status')
  @OpenAPI({ summary: '更新用户状态' })
  @Log({
    bizType: 'users',
    operation: LogOperation.UPDATE,
    bizId: (req: { user: { id: string } }) => 'user_update_' + (req?.user?.id ?? ''),
  })
  async updateStatus(@Req() req: Request, @Res() res: Response, @Param('id') id: string) {
    await this.user.updateStatus(id);
    return new ApiResponseBuilder(req, res).success();
  }

  @Get('/reset-default-password/:id')
  @RequiredPerm('user:update:reset-password')
  @OpenAPI({ summary: '重置用户默认密码' })
  @Log({
    bizType: 'users',
    operation: LogOperation.UPDATE,
    bizId: (req: { user: { id: string } }) => 'user_reset_default_password_' + (req?.user?.id ?? ''),
  })
  async resetDefaultPassword(@Req() req: Request, @Res() res: Response, @Param('id') id: string) {
    await this.user.resetToDefault(id);
    return new ApiResponseBuilder(req, res).success();
  }
}
